package com.spring.demo.init.aop;

import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
import org.springframework.aop.support.RegexpMethodPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.spring.demo.core.advice.MixMethodAdvice;
import com.spring.demo.core.service.impl.SimpleService;

@Configuration
public class AopConfig {

	private SimpleService simpleService() {
		SimpleService simpleService = new SimpleService();
		simpleService.setId(12345);
		simpleService.setName("Hello");

		return simpleService;
	}

	@Bean(name = "simpleServiceProxy")
	public ProxyFactoryBean proxyFactoryBean() {
		ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
		proxyFactoryBean.setTarget(simpleService());
		proxyFactoryBean.setInterceptorNames("mixMethodAdvice",
				"nameMatchAdvisor", "regexpMatchAdvisor");

		return proxyFactoryBean;
	}

	/**
	 * 名字匹配
	 * 
	 * @return
	 */
	@Bean(name = "nameMatchAdvisor")
	@Autowired
	public NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor(
			MixMethodAdvice mixMethodAdvice) {
		NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor();
		advisor.setMappedName("sayHello");
		advisor.setAdvice(mixMethodAdvice);

		return advisor;
	}

	/**
	 * 正则匹配
	 * 
	 * @return
	 */
	@Bean(name = "regexpMatchAdvisor")
	@Autowired
	public RegexpMethodPointcutAdvisor regexpMethodPointcutAdvisor(
			MixMethodAdvice mixMethodAdvice) {
		RegexpMethodPointcutAdvisor advisor = new RegexpMethodPointcutAdvisor();
		advisor.setAdvice(mixMethodAdvice);
		advisor.setPattern("com.spring.demo.core.service..*.sayHello*");

		return advisor;
	}

	@Bean(name = "mixMethodAdvice")
	public MixMethodAdvice mixMethodAdvice() {
		MixMethodAdvice mixMethodAdvice = new MixMethodAdvice();

		return mixMethodAdvice;
	}

	/**
	 * 按照bean的名字，进行aop
	 * 
	 * @return
	 */
	@Bean
	public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
		BeanNameAutoProxyCreator proxyCreator = new BeanNameAutoProxyCreator();
		proxyCreator.setBeanNames("order*");
		proxyCreator.setInterceptorNames("mixMethodAdvice");

		return proxyCreator;
	}

	/**
	 * 默认给所有的service 进行aop
	 * 
	 * @return
	 */
	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		return new DefaultAdvisorAutoProxyCreator();
	}
}
